home *** CD-ROM | disk | FTP | other *** search
/ 5 Star Games: DOS Edition 2 / 5 Star Games - DOS Edition (1995)(Ready to Run).iso / dbc / db_man.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-06  |  28.1 KB  |  1,209 lines

  1. /****************************************************************************/
  2. /*                         DATABOSS MODULE: DB_MAN.C                        */
  3. /****************************************************************************/
  4.  
  5. #include "db_lsc.h"
  6.  
  7. #ifndef __TURBOC__
  8.     #include <graph.h>
  9.     #include <sys\types.h>
  10.      #define _close(h) close(h)
  11. #endif
  12. #include <io.h>
  13. #include <fcntl.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <sys\stat.h>
  18.  
  19. #include "db_types.h"
  20. #include "db_curs.h"
  21. #include "db_file.h"
  22. #include "db_funcs.h"
  23. #include "db_gvar.h"
  24. #include "db_heap.h"
  25. #include "db_key.h"
  26. #include "db_math.h"
  27. #include "db_str.h"
  28. #include "db_win.h"
  29. #include "db_mnu.h"
  30. #include "db_util.h"
  31. #include "db_man.h"
  32. #include "db_uwin.h"
  33.  
  34. /****************************  GLOBAL VARIABLES  ****************************/
  35.  
  36. bool manrecur;
  37.  
  38. /***************************  INTERNAL CONSTANTS  ***************************/
  39.  
  40. #define PaperLen     66
  41. #define GoodLines    60
  42. #define MaxLines     100
  43. #define MaxIOP       100
  44.  
  45. /*****************************  INTERNAL TYPES  *****************************/
  46.  
  47. typedef struct ixfind {
  48.     uchar ich;
  49.     int ipg;
  50.     int ixp;
  51.     int iyp;
  52.     int split;
  53.     str4 pgstr;
  54. } ixfind;
  55. typedef struct ovfind {
  56.     int opg;
  57.     int oyp;
  58.     str4 pgstr;
  59. } ovfind;
  60. typedef struct manrec {
  61.     string name;
  62.     long endfile;
  63. } manrec;
  64.  
  65. /***************************  INTERNAL VARIABLES  ***************************/
  66.  
  67. static uchar blank[] = "\xFF\x01\x50 ";
  68.  
  69. static byte whb = 0x1F;
  70. static byte yhb = 0x1E;
  71. static byte rhb = 0x1C;
  72. static byte whc = 0x3F;
  73.  
  74. static pathstr outdev;
  75. static int out;
  76. static byte wrattr;
  77. static long lines[MaxLines+1];
  78. static winptr mw,cwinp;
  79. static word pageno;
  80. static int manfile;
  81. static manhdr manh;
  82. static manrec manual;
  83. static prefaptr mpages;
  84. static crefaptr mchaps;
  85. static pref ipages[MaxIOP+1];
  86. static pref opages[MaxIOP+1];
  87. static ixfind ixf;
  88. static ovfind ovf;
  89. static string crossref;
  90. static mnufrec rm;
  91.  
  92. static bool initialized = False;
  93.  
  94. /*****************************  IMPLEMENTATION  *****************************/
  95.  
  96. void writeout(string wstr, byte wa, byte wx, byte wy)
  97. {
  98.     int p;
  99.     string ts,twstr;
  100.  
  101.     strcpy(twstr,wstr);
  102.     if (outdev[0] == '\0')
  103.         writewxy(twstr,wa,wx,wy,mw);
  104.     else {
  105.         p = strposstr("\xFF\x02",twstr);
  106.         while (p >= 0) {
  107.             strdelete(twstr,p,3);
  108.             p = strposstr("\xFF\x02",twstr);
  109.         }
  110.         p = strposstr("\xFF\x01",twstr);
  111.         while ((p >= 0) && (p < (strlen(twstr)-3))) {
  112.             fillstr(ts,twstr[p+2],twstr[p+3]);
  113.             strdelete(twstr,p,4);
  114.             strinsert(ts,twstr,p);
  115.             p = strposstr("\xFF\x01",twstr);
  116.         }
  117.         for (p = 0; p < strlen(twstr); p++)
  118.             twstr[p] = filterch(twstr[p],IBMGraphics);
  119.         chkwrite(out,twstr,True);
  120.         if (pabort > 0) outdev[0] = '\0';
  121.     }
  122. }
  123.  
  124. void setcpos(word yp, word xofs, string ts)
  125. {
  126.     int i;
  127.  
  128.     ixf.iyp = yp;
  129.     ixf.ixp = strposch(',',ts);
  130.     if (ixf.ixp >= 0) {
  131.         ixf.ixp++;
  132.         strcopy(ixf.pgstr,ts,ixf.ixp,4);
  133.         i = strposch(',',ixf.pgstr);
  134.         if (i >= 0) strcopy(ixf.pgstr,ixf.pgstr,0,i);
  135.         strip(ixf.pgstr,ixf.pgstr);
  136.         ixf.ixp += xofs;
  137.     }
  138.     ixf.ixp++;
  139. }
  140.  
  141. void ixpage(word maxl, word ipno, bool active, winptr mw)
  142. {
  143.     word half,b,i,j;
  144.     byte len;
  145.     string ts,tts;
  146.  
  147.     mw->disp = False;
  148.     i = 1;
  149.     j = 0;
  150.     if (ipno == 1) ixf.ich = ' ';
  151.     half = mw->mwid/2;
  152.     lseek(manfile,ipages[ipno],SEEK_SET);
  153.     do {
  154.         if ((tell(manfile) < manual.endfile) && (i <= maxl-2)) {
  155.             if ((outdev[0] != '\0') && (i > GoodLines)) {
  156.                 writeout("\x0C",0,1,(byte) i);
  157.                 i = 1;
  158.                 j = 0;
  159.             }
  160.             read(manfile,&len,1);
  161.             if (len > 0) read(manfile,ts,len);
  162.             ts[len] = '\0';
  163.         }
  164.         else
  165.             strcpy(ts," ");
  166.         if ((ts[0] != ixf.ich) && (ts[0] != ' ')) {
  167.             if (((byte) ts[0]) > ((byte) ixf.ich)) {
  168.                 if (active) {
  169.                     strcpy(tts,"« »");
  170.                     tts[1] = ts[0];
  171.                     writeout(pad(tts,tts,half,Right),(byte)(revattr(whc)|0x08),(byte)(j*half+1),(byte)(i));
  172.                 }
  173.                 i++;
  174.                 if (i > maxl) {
  175.                     i = 1;
  176.                     j++;
  177.                 }
  178.             }
  179.             ixf.ich = ts[0];
  180.         }
  181.         if (strlen(ts) >= half) {
  182.             if (active) {
  183.                 b = half-1;
  184.                 while ((b > (half - 7)) && (ts[b-1] != ',')) b--;
  185.                 writeout(pad(tts,strcopy(tts,ts,0,b-1),half,Right),whc,(byte)(j*half+1),(byte)(i));
  186.                 if (ixf.ixp == 0) {
  187.                     setcpos(i,0,strcopy(tts,ts,0,b-1));
  188.                     if (ixf.ixp != 0) ixf.split = 1;
  189.                 }
  190.                 strdelete(ts,0,b-1);
  191.                 strinsert("  ",ts,0);
  192.             }
  193.             i++;
  194.             if (i > maxl) {
  195.                 i = 1;
  196.                 j++;
  197.             }
  198.         }
  199.         if (active && ((outdev[0] == '\0') || (strcmp(ts," ") != 0))) {
  200.             pad(ts,ts,half,Right);
  201.             writeout(ts,whc,(byte)(j*half+1),(byte)(i));
  202.             if (ixf.ixp == 0) setcpos(i,0,ts);
  203.         }
  204.         i++;
  205.         if (i > maxl) {
  206.             i = 1;
  207.             j++;
  208.         }
  209.     } while (j <= 1);
  210.     if (outdev[0] != '\0') writeout("\x0C",0,1,(byte) i);
  211.     mw->disp = True;
  212. }
  213.  
  214. void ovpage(word maxl, word opno, bool active, winptr mw)
  215. {
  216.     int i,lastnum;
  217.     string s1,s2,tl,ts;
  218.     byte len;
  219.  
  220.     mw->disp = False;
  221.     i = 1;
  222.     lastnum = 0;
  223.     lseek(manfile,opages[opno],SEEK_SET);
  224.     do {
  225.         if ((tell(manfile) < manh.sindex) && (i <= (maxl-1))) {
  226.             if ((outdev[0] != '\0') && (i > GoodLines)) {
  227.                 writeout("\x0C",0,1,(byte) i);
  228.                 i = 1;
  229.             }
  230.             read(manfile,&len,1);
  231.             if (len > 0) read(manfile,s1,len);
  232.             s1[len] = '\0';
  233.             read(manfile,&len,1);
  234.             if (len > 0) read(manfile,s2,len);
  235.             s2[len] = '\0';
  236.             strcpy(tl,s2);
  237.             strcpy(ts,"\xFF\x01 .");
  238.             ts[2] = mw->mwid-6-strlen(tl);
  239.             strcat(tl,ts);
  240.             read(manfile,&len,1);
  241.             if (len > 0) read(manfile,s2,len);
  242.             s2[len] = '\0';
  243.             strcat(tl,pad(ts,s2,5,Left));
  244.             strcat(tl," ");
  245.             if (((int) fint(valu(s1))) > lastnum) {
  246.                 if (i > 1) {
  247.                     if (active) writeout(blank,whc,1,(byte) i);
  248.                     i++;
  249.                 }
  250.                 lastnum = (int) fround(fint(valu(s1)));
  251.             }
  252.             if (active) writeout(tl,whc,1,(byte) i);
  253.         }
  254.         else {
  255.             strcpy(s1," ");
  256.             strcpy(s2," ");
  257.             strcpy(tl,blank);
  258.             if (active && (outdev[0] == '\0')) writeout(tl,whc,1,(byte) i);
  259.         }
  260.         i++;
  261.     } while (i <= maxl);
  262.     if (outdev[0] != '\0') writeout("\x0C",0,1,(byte) i);
  263.     mw->disp = True;
  264. }
  265.  
  266. void initmanual(pathstr manname)
  267. {
  268.     word w;
  269.     wintyp tw;
  270.     string ts;
  271.     byte len;
  272.  
  273.     if (manstate == _opened) {
  274.         outdev[0] = '\0';
  275.         pageno = 1;
  276.         manrecur = False;
  277.         db_free(mpages);
  278.         db_free(mchaps);
  279.         _close(manfile);
  280.     }
  281.     if (manstate == _located) {
  282.         wrattr = swc;
  283.         message(NULL,centre(ts,LSC_LoadingManual,76));
  284.         manual.endfile = filelength(manfile);
  285.         read(manfile,(void *)&manh,sizeof(manhdr));
  286.         mpages =   db_malloc((manh.totpages+2)*sizeof(pref));
  287.         mchaps = db_malloc((manh.totchaps+2)*sizeof(cref));
  288.         lseek(manfile,manh.sinfo,SEEK_SET);
  289.         for (w = 1; w <= manh.totpages; w++)
  290.             read(manfile,(void *)&(*mpages)[w],sizeof(pref));
  291.         for (w = 1; w <= manh.totchaps; w++)
  292.             read(manfile,(void *)&(*mchaps)[w],sizeof(cref));
  293.         read(manfile,&len,1);
  294.         if (len > 0) {
  295.             read(manfile,manual.name,len);
  296.             manual.name[len] = 0;
  297.         }
  298.         manh.totpages--;
  299.         manh.totchaps--;
  300.         tw.mhgt = scrhgt - 5;
  301.         tw.mwid = scrwid - 2;
  302.         ixf.ipg = 1;
  303.         ipages[1] = manh.sindex;
  304.         lseek(manfile,manh.sindex,SEEK_SET);
  305.         do {
  306.             ixpage(tw.mhgt,ixf.ipg,False,&tw);
  307.             ixf.ipg++;
  308.             ipages[ixf.ipg] = tell(manfile);
  309.         } while (tell(manfile) < manual.endfile);
  310.         for (w = ixf.ipg; w <= MaxIOP; w++) ipages[w] = 0;
  311.         ovf.opg = 1;
  312.         opages[1] = manh.soview;
  313.         lseek(manfile,manh.soview,SEEK_SET);
  314.         do {
  315.             ovpage(tw.mhgt,ovf.opg,False,&tw);
  316.             ovf.opg++;
  317.             opages[ovf.opg] = tell(manfile);
  318.         } while (tell(manfile) < manh.sindex);
  319.         for (w = ovf.opg; w <= MaxIOP; w++) opages[w] = 0;
  320.         manstate = _opened;
  321.         message(NULL,"");
  322.     }
  323.     else {
  324.         manstate = _closed;
  325.         fsearch(ts,manname,lookalong);
  326.         if (ts[0] == '\0') strcpy(ts,manname);
  327.         manfile = open(ts,O_BINARY | O_RDWR, S_IREAD | S_IWRITE);
  328.         if (manfile == -1) manstate = _lost; else manstate = _located;
  329.     }
  330. }
  331.  
  332. void nextcpos(byte dirn)
  333. {
  334.     int tpos,half,i,j,ty1,ty2,l1;
  335.     string tl,ts,ta;
  336.  
  337.     half = mw->mwid/2;
  338.     i = ixf.iyp;
  339.     j = (ixf.ixp < half) ? 0 : 1;
  340.     if ((dirn == _Left_) || (dirn == _Right_)) {
  341.         if (ixf.split > 0) {
  342.             if (ixf.split == 1) {
  343.                 ty1 = ixf.iyp;
  344.                 ty2 = ty1 + 1;
  345.             }
  346.             else {
  347.                 ty2 = ixf.iyp;
  348.                 ty1 = ty2-1;
  349.             }
  350.             getline((byte)(j*half+1),(byte)(ty1),(byte)(half),tl,ta,mw);
  351.             trim(tl,tl);
  352.             l1 = strlen(tl);
  353.             getline((byte) (j*half+1),(byte)(ty2),(byte)(half),ts,ta,mw);
  354.             strcat(tl,mirt(ts,ts));
  355.         }
  356.         else
  357.             getline((byte)(j*half+1),(byte)(ixf.iyp),(byte)(half),tl,ta,mw);
  358.     }
  359.     switch (dirn) {
  360.         case _Up_ :
  361.             do {
  362.                 i--;
  363.                 if (i <= 0) {
  364.                     i = mw->mhgt;
  365.                     j--;
  366.                 }
  367.                 if (j >= 0)
  368.                     getline((byte)(j*half+1),(byte)(i),(byte)(half),tl,ta,mw);
  369.                 else
  370.                     tl[0] = '\0';
  371.             } while ((j >= 0) && ((strcmp(strcopy(ts,tl,0,2),"  ") == 0) ||
  372.                                 (strposch(',',tl) == -1)));
  373.             if (j >= 0) {
  374.                 setcpos(i,(j*half),tl);
  375.                 ixf.split = 0;
  376.                 if (i < mw->mhgt) {
  377.                     getline((byte)(j*half+1),(byte)(i+1),(byte)(half),tl,ta,mw);
  378.                     if ((strcmp(strcopy(ts,tl,0,2),"  ") == 0) && (strposch(',',tl) >= 0))
  379.                         ixf.split = 1;
  380.                 }
  381.             }
  382.         break;
  383.         case _Down_ :
  384.             do {
  385.                 i++;
  386.                 if (i > mw->mhgt) {
  387.                     i = 1;
  388.                     j++;
  389.                 }
  390.                 if (j < 2)
  391.                     getline((byte)(j*half+1),(byte)(i),(byte)(half),tl,ta,mw);
  392.                 else
  393.                     tl[0] = '\0';
  394.             } while ((j <= 1) && ((strcmp(strcopy(ts,tl,0,2),"  ") == 0) || (strposch(',',tl) < 0)));
  395.             if (j <= 1) {
  396.                 setcpos(i,(j*half),tl);
  397.                 ixf.split = 0;
  398.                 if (i < mw->mhgt) {
  399.                     getline((byte)(j*half+1),(byte)(i+1),(byte)(half),tl,ta,mw);
  400.                     if ((strcmp(strcopy(ts,tl,0,2),"  ") == 0) && (strposch(',',tl) >= 0))
  401.                         ixf.split = 1;
  402.                 }
  403.             }
  404.         break;
  405.         case _Left_ :
  406.             ts[0] = ',';
  407.             strcpy(&ts[1],ixf.pgstr);
  408.             tpos = strposstr(ts,tl);
  409.             if (tpos >= 0) {
  410.                 do {
  411.                     tpos--;
  412.                 } while ((tpos >= 0) && (tl[tpos] != ','));
  413.             }
  414.             if (tpos >= 0) {
  415.                 setcpos(ixf.iyp,(j*half),strcopy(ts,tl,tpos,12));
  416.                 ixf.ixp = ixf.ixp + tpos;
  417.                 if (ixf.split > 0) {
  418.                     if (ixf.ixp > l1)
  419.                         ixf.ixp = ixf.ixp + 2 - l1;
  420.                     else {
  421.                         if (ixf.split == 2) {
  422.                             ixf.iyp--;
  423.                             ixf.split--;
  424.                         }
  425.                     }
  426.                 }
  427.             }
  428.         break;
  429.         case _Right_ :
  430.             strcpy(ts,ixf.pgstr);
  431.             strcat(ts,",");
  432.             tpos = strposstr(ts,tl);
  433.             if (tpos >= 0) {
  434.                 setcpos(ixf.iyp,(j*half),strcopy(ts,tl,tpos,12));
  435.                 ixf.ixp = ixf.ixp + tpos;
  436.                 if ((ixf.split > 0) && (ixf.ixp > l1)) {
  437.                     if (ixf.split == 1) {
  438.                         ixf.iyp++;
  439.                         ixf.split++;
  440.                     }
  441.                     ixf.ixp = ixf.ixp + 2 - l1;
  442.                 }
  443.             }
  444.         break;
  445.     }
  446. }
  447.  
  448. word findix(string str)
  449. {
  450.     word w;
  451.  
  452.     w = 0;
  453.     do {
  454.         w++;
  455.         if (ipages[w] != 0) ixpage(mw->mhgt,w,False,mw);
  456.     } while ((((byte) ixf.ich) < ((byte) str[0])) && (ipages[w] != 0));
  457.     return ((ipages[w] != 0) ? w : w-1);
  458. }
  459.  
  460. void placeix(string str, bool active)
  461. {
  462.     word i,j,half,oldp;
  463.     string ts,ta;
  464.  
  465.     i = (strlen(str) < 2) ? findix(str) : ixf.ipg;
  466.     do {
  467.         oldp = ixf.ipg;
  468.         ixf.ipg = i;
  469.         if (ixf.ipg != oldp) {
  470.             ixf.ixp = 0;
  471.             ixpage(mw->mhgt,ixf.ipg,active,mw);
  472.         }
  473.         i = 0;
  474.         j = 0;
  475.         half = mw->mwid/2;
  476.         do {
  477.             i++;
  478.             if (i > mw->mhgt) {
  479.                 i = 1;
  480.                 j++;
  481.             }
  482.             getline((byte)(j*half+1),(byte)(i),(byte)(half),ts,ta,mw);
  483.         } while (((strcmp(ts,str) < 0) || (ts[0] == 0xAE)) && (j <= 1));
  484.         if (j < 2) {
  485.             ixf.iyp = i;
  486.             ixf.ixp = (j == 0) ? 1 : half+1;
  487.             if (strposch(',',ts) < 0)
  488.                 nextcpos(_Down_);
  489.             else
  490.                 setcpos(i,(j*half),ts);
  491.             i = ixf.ipg;
  492.         }
  493.         else
  494.             i = ixf.ipg + 1;
  495.     } while ((j >= 2) && (ipages[i] != 0));
  496.     if (active && (oldp != ixf.ipg)) dispwindow(mw);
  497. }
  498.  
  499. word pickfromindex(str40 fs, word pno)
  500. {
  501.     word half,w;
  502.     byte ukey;
  503.     bool refill;
  504.     ixfind savixf;
  505.     string ts,tfs;
  506.  
  507.     strcpy(tfs,fs);
  508.     refill = True;
  509.     half = mw->mwid/2;
  510.     savixf = ixf;
  511.     writewxy(blank,0,1,1,cwinp);
  512.     do {
  513.         if (refill) {
  514.             ixpage(mw->mhgt,ixf.ipg,True,mw);
  515.             dispwindow(mw);
  516.             refill = False;
  517.         }
  518.         if (tfs[0] != '\0') placeix(tfs,True);
  519.         writewxy(ixf.pgstr,0xF0,(byte) ixf.ixp,(byte) ixf.iyp,mw);
  520.         ukey = upperch(getkey());
  521.         writewxy(ixf.pgstr,whc,(byte) ixf.ixp,(byte) ixf.iyp,mw);
  522.         if ((ukey == BackSp) || ((ukey >= '0') && (ukey <= '9')) ||
  523.                 ((ukey >= 'A') && (ukey <= 'Z'))) {
  524.             if (ukey != BackSp)
  525.                 strcat(tfs,chstr(ts,ukey));
  526.             else {
  527.                 if (tfs[0] != '\0') tfs[strlen(tfs)-1] = '\0';
  528.             }
  529.             strconcat(ts,LSC_SearchFor,"\"",tfs,"\" ",NULL);
  530.             writewxy(ts,yhb,1,1,cwinp);
  531.         }
  532.         else {
  533.             tfs[0] = '\0';
  534.             writewxy(blank,0,1,1,cwinp);
  535.         }
  536.         switch (ukey) {
  537.             case Tab :
  538.                 if (ixf.ixp > half) {
  539.                     ixf.ixp = 1;
  540.                     nextcpos(_Down_);
  541.                 }
  542.                 else {
  543.                     if (ixf.ixp > 0) {
  544.                     ixf.ixp = half+1;
  545.                     nextcpos(_Up_);
  546.                 }
  547.             } break;
  548.             case UArr : nextcpos(_Up_); break;
  549.             case DArr : nextcpos(_Down_); break;
  550.             case LArr : nextcpos(_Left_); break;
  551.             case RArr : nextcpos(_Right_); break;
  552.             case PgUp :
  553.                 if (ixf.ipg > 1) {
  554.                     ixf.ipg--;
  555.                     ixf.ixp = 0;
  556.                     refill = True;
  557.                 }
  558.             break;
  559.             case PgDn :
  560.                 if ((ixf.ipg < MaxIOP) && (ipages[ixf.ipg+1] != 0)) {
  561.                     ixf.ipg++;
  562.                     ixf.ixp = 0;
  563.                     refill = True;
  564.                 }
  565.             break;
  566.         }
  567.     } while ((ukey != Enter) && (ukey != QitKey));
  568.     if (ukey == Enter)
  569.         w = (word) ival(ixf.pgstr);
  570.     else {
  571.         w = pno;
  572.         ixf = savixf;
  573.     }
  574.     return (w);
  575. }
  576.  
  577. word pickfromoview(word pno)
  578. {
  579.     int i;
  580.     uchar ukey;
  581.     bool refill;
  582.     ovfind savovf;
  583.     uchar ta[5];
  584.     word fval;
  585.  
  586.     refill = True;
  587.     savovf = ovf;
  588.     do {
  589.         if (refill) {
  590.             ovpage(mw->mhgt,ovf.opg,True,mw);
  591.             getline((byte)(mw->mwid-4),(byte)(ovf.oyp),4,ovf.pgstr,ta,mw);
  592.             dispwindow(mw);
  593.             refill = False;
  594.         }
  595.         writewxy(ovf.pgstr,0xF0,(byte)(mw->mwid-4),(byte)(ovf.oyp),mw);
  596.         ukey = upperch(getkey());
  597.         writewxy(ovf.pgstr,whc,(byte)(mw->mwid-4),(byte)(ovf.oyp),mw);
  598.         switch (ukey) {
  599.             case UArr :
  600.                 if (ovf.oyp > 1) {
  601.                     do {
  602.                         ovf.oyp--;
  603.                         getline((byte)(mw->mwid-4),(byte)(ovf.oyp),4,ovf.pgstr,ta,mw);
  604.                     } while ((ovf.oyp != 1) && (ival(ovf.pgstr) <= 0));
  605.                 }
  606.             break;
  607.             case DArr :
  608.                 if (ovf.oyp < mw->mhgt) {
  609.                     i = ovf.oyp;
  610.                     do {
  611.                         i++;
  612.                         getline((byte)(mw->mwid-4),(byte)(i),4,ovf.pgstr,ta,mw);
  613.                     } while ((i < mw->mhgt) && (ival(ovf.pgstr) <= 0));
  614.                     if (ival(ovf.pgstr) > 0)
  615.                         ovf.oyp = i;
  616.                     else
  617.                         getline((byte)(mw->mwid-4),(byte)(ovf.oyp),4,ovf.pgstr,ta,mw);
  618.                 }
  619.             break;
  620.             case PgUp :
  621.                 if (ovf.opg > 1) {
  622.                     ovf.opg--;
  623.                     refill = True;
  624.                     ovf.oyp = 1;
  625.                 }
  626.             break;
  627.             case PgDn :
  628.                 if ((ovf.opg < MaxIOP) && (opages[ovf.opg+1] != 0)) {
  629.                     ovf.opg++;
  630.                     refill = True;
  631.                     ovf.oyp = 1;
  632.                 }
  633.             break;
  634.         }
  635.     } while ((ukey != Enter) && (ukey != QitKey));
  636.     if (ukey == Enter)
  637.         fval = (word) ival(ovf.pgstr);
  638.     else {
  639.         fval = pno;
  640.         ovf = savovf;
  641.     }
  642.     return (fval);
  643. }
  644.  
  645. void additm(mnufrec *m, string pr)
  646. {
  647.     string ts;
  648.     int tslen;
  649.     mnuptr cm;
  650.     itmptr ci;
  651.  
  652.     m->curitm = (itmptr) db_malloc(sizeof(itmtyp));
  653.     m->curitm->selcmd  = (strptr) db_malloc(1); m->curitm->selcmd[0]  = '\0';
  654.     m->curitm->selpath = (strptr) db_malloc(1); m->curitm->selpath[0] = '\0';
  655.     m->curitm->selact  = (strptr) db_malloc(1); m->curitm->selact[0]  = '\0';
  656.     strcpy(ts,pr);
  657.     tslen = strlen(ts);
  658.     m->curitm->prompt = (strptr) db_malloc(tslen+1);
  659.     cm = m->curmnu;
  660.     ci = m->curitm;
  661.     if ((tslen+2) > cm->widm) cm->widm = (byte) (tslen + 2);
  662.     cm->hgtm++;
  663.     strcpy(ci->prompt,ts);
  664.     ci->ix = 2;
  665.     ci->iy = cm->hgtm;
  666.     ci->prpos = 1;
  667.     ci->sec = 0;
  668.     ci->editsec = 0;
  669.     ci->helpwin = NULL;
  670.     ci->selwait = _NO;
  671.     ci->seltyp = ' ';
  672.     strcpy(ci->altern.altcomb,"   ");
  673.     ci->altern.nxtalt = NULL;
  674.     ci->altern.parmnu = NULL;
  675.     if (cm->fitm == NULL) {
  676.         cm->fitm = ci;
  677.         ci->nitm = ci;
  678.         ci->pitm = ci;
  679.     }
  680.     else {
  681.         ci->pitm = cm->fitm->pitm;
  682.         ci->nitm = cm->fitm;
  683.         cm->fitm->pitm->nitm = ci;
  684.         cm->fitm->pitm = ci;
  685.     }
  686. }
  687.  
  688. void makemnu(mnufrec *m)
  689. {
  690.     mnuptr mnu;
  691.  
  692.     mnu = (mnuptr) db_malloc(sizeof(mnutyp));
  693.     m->mat[0] = mnu;
  694.     mnu->hitm = NULL;
  695.     mnu->winp = NULL;
  696.     mnu->litm = NULL;
  697.     mnu->fitm = NULL;
  698.     mnu->mtyp = Vert;
  699.     mnu->mno = 1;
  700.     mnu->pmnu = 0;
  701.     mnu->xm = 2;
  702.     mnu->ym = 2;
  703.     mnu->widm = 2;
  704.     mnu->hgtm = 0;
  705.     mnu->mnucolr = 15;
  706.     mnu->mbcolr = 9;
  707.     mnu->mshad = 8;
  708.     memcpy(mnu->mbchrs,"─┐│┘─└│┌",8);
  709.     mnu->mtitlej = TopCnt;
  710.     mnu->mtitle[0] = '\0';
  711.     mnu->apc = 3;
  712.     mnu->ipc = 7;
  713.     mnu->hc = 14;
  714.     mnu->sl = 0;
  715.     mnu->hbc = 112;
  716.     m->curmnu = mnu;
  717. }
  718.  
  719. void killmnu(mnufrec *m)
  720. {
  721.     itmptr titm;
  722.  
  723.     zapmnu(m,m->mat[0]);
  724.     titm = m->curmnu->fitm->pitm;
  725.     while (titm != m->curmnu->fitm) {
  726.         titm = titm->pitm;
  727.         db_free(titm->nitm);
  728.     }
  729.     db_free(m->curmnu->fitm);
  730.     db_free(m->curmnu);
  731. }
  732.  
  733. strptr xref(str40 sout, string ts)
  734. {
  735.     int b;
  736.     uchar ukey;
  737.     str40 wkstr;
  738.     string tts;
  739.     uchar ukeystr[2];
  740.  
  741.     trim(tts,mirt(tts,ts));
  742.     if (tts[0] != '\0') {
  743.         for (b = 0; b < MaxMnus; b++) rm.mat[b] = NULL;
  744.         makemnu(&rm);
  745.         rm.curmnu = rm.mat[0];
  746.         rm.curitm = NULL;
  747.         rm.mnufnam[0] = '\0';
  748.         rm.basewin1 = NULL;
  749.         rm.basewin2 = NULL;
  750.         rm.level = 0;
  751.         rm.dx = 0;
  752.         rm.dy = 0;
  753.         rm.altcomb1 = NULL;
  754.         ukey = 'A';
  755.         while ((tts[0] != '\0') && (ukey <= 'W')) {
  756.             b = strposch('|',tts);
  757.             if (b >= 0) {
  758.                 trim(wkstr,mirt(wkstr,strcopy(wkstr,tts,0,b)));
  759.                 strdelete(tts,0,b+1);
  760.             }
  761.             else {
  762.                 trim(wkstr,mirt(wkstr,tts));
  763.                 tts[0] = '\0';
  764.             }
  765.             if (wkstr[0] != '\0') {
  766.                 strconcat(wkstr,chstr(ukeystr,ukey)," - ",wkstr,NULL);
  767.                 ukey++;
  768.                 additm(&rm,wkstr);
  769.             }
  770.         }
  771.         rm.curitm = rm.curmnu->fitm;
  772.         rm.mat[0]->xm = (scrwid-rm.mat[0]->widm)/2;
  773.         rm.mat[0]->ym = (scrhgt-rm.mat[0]->hgtm)/2;
  774.         dspmnu(&rm,rm.mat[0]);
  775.         do {
  776.             hbar(&rm);
  777.             ukey = upperch(getkey());
  778.             switch (ukey) {
  779.                 case UArr   : goud(&rm,Up); break;
  780.                 case DArr   : goud(&rm,Down); break;
  781.                 case Enter  : strcpy(sout,rm.curitm->prompt); break;
  782.                 case QitKey : sout[0] = '\0'; break;
  783.                 default     :
  784.                     if ((ukey >= 'A') && (ukey <= 'Z'))
  785.                         selitm(ukey,&rm);
  786.                 break;
  787.             }
  788.         } while ((ukey != Enter) && (ukey != QitKey));
  789.         killmnu(&rm);
  790.     }
  791.     else {
  792.         sout[0] = '\0';
  793.         dberrm(LSC_NoXRefHere);
  794.     }
  795.     return (sout);
  796. }
  797.  
  798. void dspln(int lno, int p, int maxl)
  799. {
  800.     byte b;
  801.     string ts;
  802.     uchar as[5];
  803.  
  804.     read(manfile,&b,1);
  805.     if (b > 0) read(manfile,ts,b);
  806.     ts[b] = '\0';
  807.     if (tell(manfile) >= (*mpages)[p+1]) {
  808.         strcpy(crossref,ts);
  809.         lines[lno] = 0;
  810.         if (lno <= maxl) writeout(blank,wrattr,1,(byte) lno);
  811.     }
  812.     else {
  813.         if (lno <= maxl) {
  814.             b = eslen(ts);
  815.             if (b < mw->mwid) {
  816.                 strcpy(as,"\xFF\x01  ");
  817.                 as[2] = mw->mwid-b;
  818.                 strcat(ts,as);
  819.             }
  820.             writeout(ts,wrattr,1,(byte) lno);
  821.             if (strposstr("\xFF\x02",ts) >= 0) {
  822.                 b = (byte) (strlen(ts)-4);
  823.                 while ((ts[b] != 0xFF) || (ts[b+1] != 0x02)) b--;
  824.                 wrattr = ts[b+2];
  825.             }
  826.         }
  827.     }
  828. }
  829.  
  830. void loadpage(word pno, int maxl)
  831. {
  832.     int lno;
  833.  
  834.     crossref[0] = '\0';
  835.     mw->disp = False;
  836.     lno = 1;
  837.     lseek(manfile,(*mpages)[pno],SEEK_SET);
  838.     do {
  839.         if (tell(manfile) >= (*mpages)[pno+1]) {
  840.             lines[lno] = 0;
  841.             if ((lno <= maxl) && (outdev[0] == '\0')) writeout(blank,wrattr,1,(byte) lno);
  842.         }
  843.         else {
  844.             lines[lno] = tell(manfile);
  845.             dspln(lno,pno,maxl);
  846.         }
  847.         lno++;
  848.     } while (lno <= MaxLines);
  849.     mw->disp = True;
  850. }
  851.  
  852. int getchap(word pno)
  853. {
  854.     int fval;
  855.  
  856.     fval = 0;
  857.     do fval++; while (((*mchaps)[fval] <= pno) && (fval <= manh.totchaps));
  858.     return (fval-1);
  859. }
  860.  
  861. void updatepage(word pno, bool lup, bool ldn)
  862. {
  863.     string ts,tts;
  864.  
  865.     strconcat(ts,LSC_Chapter,istr(ts,(long) getchap(pno),4),", [",
  866.                         strip(tts,istr(tts,(long) manh.totchaps,4)),"]",NULL);
  867.     writewxy(ts,yhb,2,1,cwinp);
  868.     strconcat(ts,LSC_Page,istr(ts,(long) pno,4),", [",
  869.                         strip(tts,istr(tts,(long) manh.totpages,4)),"]",NULL);
  870.     writewxy(ts,yhb,(byte)(scrwid-strlen(ts)-2),1,cwinp);
  871.     if (lup || ldn) {
  872.         strcpy(ts,LSC_EndOfPage);
  873.         if (lup) ts[0] = '\x18';
  874.         if (ldn) ts[strlen(ts)-1] = '\x19';
  875.     }
  876.     else
  877.         pad(ts,"",strlen(LSC_EndOfPage),Right);
  878.     writewxy(ts,yhb,(byte)((cwinp->mwid-strlen(ts))/2),1,cwinp);
  879. }
  880.  
  881. bool chkpage(string instr)
  882. {
  883.     return ((bool) ((ival(instr) >= 1) && (ival(instr) <= manh.totpages)));
  884. }
  885.  
  886. bool chkchap(string instr)
  887. {
  888.     return ((bool) ((ival(instr) >= 1) && (ival(instr) <= manh.totchaps)));
  889. }
  890.  
  891. bool chkdev(string instr)
  892. {
  893.     string ts,tts;
  894.  
  895.     return ((bool) ((strcmp(strip(ts,instr),trim(tts,instr)) == 0) &&
  896.                                     (strcmp(strip(ts,instr),"CON") != 0)));
  897. }
  898.  
  899. void printman(word pno)
  900. {
  901.     string ts,ts1,ts2,ts3,ts4;
  902.     uchar form[4];
  903.     word w,last,first;
  904.     int savds;
  905.  
  906.     first = pageno;
  907.     last = pageno;
  908.     strconcat(ts,LSC_PrintOverview,"|",LSC_PrintIndex,"|",LSC_PrintByPages,"|",LSC_PrintByChapters,NULL);
  909.     xref(ts,ts);
  910.     if (ts[0] != '\0') {
  911.         exitcode = ' ';
  912.         form[0] = '4';
  913.         form[1] = Pic_H;
  914.         form[2] = '\0';
  915.         switch (ts[0]) {
  916.             case 'C' :
  917.                 dbgetstr(ts1,_Num,strconcat(ts2,LSC_EnterBeginning," ",LSC_Page,NULL),
  918.                                     fstr(ts3,(double) first,4,0),form,
  919.                                     strconcat(ts4,LSC_Page," ",LSC_OutOfRange,NULL),chkpage,nohelp);
  920.                 first = (word) ival(ts1);
  921.                 if (exitcode != QitKey) {
  922.                     dbgetstr(ts1,_Num,strconcat(ts2,LSC_EnterEnding," ",LSC_Page,NULL),
  923.                                         fstr(ts3,(double) first,4,0),form,
  924.                                         strconcat(ts4,LSC_Page," ",LSC_OutOfRange,NULL),chkpage,nohelp);
  925.                     last = (word) ival(ts1);
  926.                 }
  927.                 if (first > last) exitcode = QitKey;
  928.             break;
  929.             case 'D' :
  930.                 dbgetstr(ts1,_Num,strconcat(ts2,LSC_EnterBeginning," ",LSC_Chapter,NULL),
  931.                                     fstr(ts3,(double) first,4,0),form,
  932.                                     strconcat(ts4,LSC_Chapter," ",LSC_OutOfRange,NULL),chkchap,nohelp);
  933.                 first = (word) ival(ts1);
  934.                 if (exitcode != QitKey) {
  935.                     dbgetstr(ts1,_Num,strconcat(ts2,LSC_EnterEnding," ",LSC_Chapter,NULL),
  936.                                         fstr(ts3,(double) first,4,0),form,
  937.                                         strconcat(ts4,LSC_Chapter," ",LSC_OutOfRange,NULL),chkchap,nohelp);
  938.                     last = (word) ival(ts1);
  939.                 }
  940.                 if (first <= last) {
  941.                     first = (*mchaps)[first];
  942.                     last = (*mchaps)[last+1]-1;
  943.                     if (last < first) last = first;
  944.                 }
  945.                 else exitcode = QitKey;
  946.             break;
  947.         }
  948.         if (exitcode != QitKey) {
  949.             strcpy(form,"12");
  950.             form[2] = Pic_U;
  951.             form[3] = '\0';
  952.             dbgetstr(ts1,_Ch,LSC_EnterOutDevice,"PRN",form,LSC_CONInvalid,chkdev,nohelp);
  953.             strcpy(outdev,strip(ts1,ts1));
  954.         }
  955.         if (exitcode != QitKey) {
  956.             savds = deltas;
  957.             deltas = 0;
  958.             out = open(outdev,O_TEXT | O_RDWR, S_IREAD | S_IWRITE);
  959.             if (out != -1) {
  960.                 message(cwinp,LSC_WaitWhilePrinting);
  961.                 switch (ts[0]) {
  962.                     case 'A' : ovpage(PaperLen,1,True,mw); break;
  963.                     case 'B' : ixpage(PaperLen,1,True,mw); break;
  964.                     case 'C' :
  965.                     case 'D' :
  966.                         for (w = first; w <= last; w++) {
  967.                             strconcat(ts1,LSC_Page," : ",istr(ts1,(long) w,4),NULL);
  968.                             writeout(pad(ts1,ts1,77,Left),1,1,1);
  969.                             loadpage(w,GoodLines);
  970.                             if (outdev[0] != '\0') writeout("\x0C",1,1,1);
  971.                         }
  972.                     break;
  973.                 }
  974.                 _close(out);
  975.                 message(cwinp,"");
  976.                 deltas = savds;
  977.             }
  978.             else
  979.                 dberrm(LSC_DeviceNotReady);
  980.         }
  981.     }
  982.     outdev[0] = '\0';
  983. }
  984.  
  985. void dispmanual(void)
  986. {
  987.     uchar ukey;
  988.     word pno;
  989.     byte b,startlno;
  990.     string ts,s;
  991.     uchar form[3];
  992.    winptr hwinp;
  993.  
  994.     if (manstate == _located) initmanual("");
  995.     if ((manstate == _opened) && (!manrecur) &&
  996.             openwin(0,2,(byte)(scrhgt-2),(byte)(scrwid-2),2,whb,whb,8,"─┐│┘─└│┌",TopCnt,"") &&
  997.             openwin(0,2,2,(byte)(scrwid-2),(byte)(scrhgt-5),whb,whb,0,"─┐│┤─├│┌",TopCnt,manual.name)) {
  998.         form[0] = '4';
  999.         form[1] = Pic_H;
  1000.         form[2] = '\0';
  1001.         manrecur = True;
  1002.         blank[2] = scrwid-2;
  1003.         mw = curwin;
  1004.         mw->disp = True;
  1005.         ixf.ipg = 1;
  1006.         ixf.ixp = 0;
  1007.         ixf.iyp = 0;
  1008.         ixf.pgstr[0] = '\0';
  1009.         ixf.ich = ' ';
  1010.         ovf.opg = 1;
  1011.         ovf.oyp = 1;
  1012.         ovf.pgstr[0] = '\0';
  1013.         cwinp = curwin->prvwin;
  1014.         writewxy(centre(ts,LSC_ManualMainMenu,cwinp->mwid),rhb,1,2,cwinp);
  1015.         loadpage(pageno,mw->mhgt); startlno = 1;
  1016.         cwinp->disp = True;
  1017.         dispwindow(cwinp);
  1018.         do {
  1019.             if (!kpressed())
  1020.                 updatepage(pageno,(bool) (startlno > 1),(bool) (lines[startlno+mw->mhgt] != 0));
  1021.             dispwindow(mw);
  1022.             ukey = upperch(getkey());
  1023.             switch (ukey) {
  1024.                 case HlpKey :  hwinp = OnLineManualHelp();
  1025.                            disphelpwin(hwinp);
  1026.                            closewin(&hwinp);
  1027.                            break;
  1028.                 case F7 :
  1029.                 case F8 :
  1030.                 case F9 :
  1031.                     ts[0] = '\0';
  1032.                     if (ukey == F7) {
  1033.                         xref(ts,crossref);
  1034.                         strcopy(ts,ts,4,strlen(ts)-4);
  1035.                         if (ts[0] != '\0')
  1036.                             ukey = F9;
  1037.                         else
  1038.                             pno = pageno;
  1039.                     }
  1040.                     if (ukey == F8) pno = pickfromoview(pageno);
  1041.                     if (ukey == F9) {
  1042.                         writewxy(centre(s,LSC_IndexMenu,cwinp->mwid),rhb,1,2,cwinp);
  1043.                         pno = pickfromindex(ts,pageno);
  1044.                     }
  1045.                     writewxy(centre(s,LSC_ManualMainMenu,cwinp->mwid),rhb,1,2,cwinp);
  1046.                     if (pno != pageno) {
  1047.                         pageno = pno;
  1048.                         loadpage(pageno,mw->mhgt);
  1049.                         startlno = 1;
  1050.                     }
  1051.                     else {
  1052.                         mw->disp = False;
  1053.                         lseek(manfile,lines[startlno],SEEK_SET);
  1054.                         for (b = 1; b <=mw->mhgt; b++) {
  1055.                             if (lines[b] != 0)
  1056.                                 dspln(b,pageno,mw->mhgt);
  1057.                             else
  1058.                                 writeout(blank,wrattr,1,b);
  1059.                         }
  1060.                         mw->disp = True;
  1061.                     }
  1062.                 break;
  1063.                 case UArr :
  1064.                     if (startlno > 1) {
  1065.                         startlno--;
  1066.                         inscroll(_Up_,mw);
  1067.                         lseek(manfile,lines[startlno],SEEK_SET);
  1068.                         dspln(1,pageno,mw->mhgt);
  1069.                     }
  1070.                 break;
  1071.                 case DArr :
  1072.                     if (((MaxLines - startlno) >= mw->mhgt) && (lines[startlno+mw->mhgt] != 0)) {
  1073.                         inscroll(_Down_,mw);
  1074.                         lseek(manfile,lines[startlno+mw->mhgt],SEEK_SET);
  1075.                         dspln(mw->mhgt,pageno,mw->mhgt);
  1076.                         startlno++;
  1077.                     }
  1078.                 break;
  1079.                 case LArr :
  1080.                 case RArr : break;
  1081.                 case PgUp :
  1082.                     if (pageno > 1) {
  1083.                         pageno--;
  1084.                         loadpage(pageno,mw->mhgt);
  1085.                         startlno = 1;
  1086.                     }
  1087.                 break;
  1088.                 case PgDn :
  1089.                     if (pageno < manh.totpages) {
  1090.                         pageno++;
  1091.                         loadpage(pageno,mw->mhgt);
  1092.                         startlno = 1;
  1093.                     }
  1094.                 break;
  1095.                 case Home :
  1096.                     mw->disp = False;
  1097.                     lseek(manfile,lines[1],SEEK_SET);
  1098.                     for (b = 1; b <= mw->mhgt; b++) {
  1099.                         if (lines[b] != 0) dspln(b,pageno,mw->mhgt);
  1100.                     }
  1101.                     startlno = 1;
  1102.                     mw->disp = True;
  1103.                 break;
  1104.                 case EndKey :
  1105.                     mw->disp = False;
  1106.                     pno = mw->mhgt;
  1107.                     while ((lines[pno+1] != 0) && (pno < MaxLines)) pno++;
  1108.                     startlno = (byte) ((pno <= mw->mhgt) ? 1 : pno - mw->mhgt + 1);
  1109.                     lseek(manfile,lines[startlno],SEEK_SET);
  1110.                     for (b = 1; b <= mw->mhgt; b++) {
  1111.                         if (lines[b] != 0) dspln(b,pageno,mw->mhgt);
  1112.                     }
  1113.                     mw->disp = True;
  1114.                 break;
  1115.                 case CtrlPgUp :
  1116.                     pno = getchap(pageno);
  1117.                     if (pno > 1) {
  1118.                         pageno = (*mchaps)[pno-1];
  1119.                         loadpage(pageno,mw->mhgt);
  1120.                         startlno = 1;
  1121.                     }
  1122.                 break;
  1123.                 case CtrlPgDn :
  1124.                     pno = getchap(pageno);
  1125.                     if (pno < manh.totchaps) {
  1126.                         pageno = (*mchaps)[pno+1];
  1127.                         loadpage(pageno,mw->mhgt);
  1128.                         startlno = 1;
  1129.                     }
  1130.                 break;
  1131.                 case CtrlHome :
  1132.                     pageno = (*mchaps)[1];
  1133.                     loadpage(pageno,mw->mhgt);
  1134.                     startlno = 1;
  1135.                 break;
  1136.                 case CtrlEnd :
  1137.                     pageno = (*mchaps)[manh.totchaps];
  1138.                     loadpage(pageno,mw->mhgt);
  1139.                     startlno = 1;
  1140.                 break;
  1141.                 case PAGE :
  1142.                     dbgetstr(s,_Num,LSC_Page,"",form,"",nocheck,nohelp);
  1143.                     pno = (word) ival(s);
  1144.                     if ((pno >= 1) && (pno <= manh.totpages)) {
  1145.                         pageno = pno;
  1146.                         loadpage(pageno,mw->mhgt);
  1147.                         startlno = 1;
  1148.                     }
  1149.                 break;
  1150.                 case CHAPTER :
  1151.                     dbgetstr(s,_Num,LSC_Chapter,"",form,"",nocheck,nohelp);
  1152.                     pno = (word) ival(s);
  1153.                     if ((pno >= 1) && (pno <= manh.totchaps)) {
  1154.                         pageno = (*mchaps)[pno];
  1155.                         loadpage(pageno,mw->mhgt);
  1156.                         startlno = 1;
  1157.                     }
  1158.                 break;
  1159.                 case Enter : break;
  1160.                 case CtrlP : printman(pageno); break;
  1161.                 case QitKey : break;
  1162.             }
  1163.         } while (ukey != QitKey);
  1164.         mw->disp = True;
  1165.         closewin(&mw);
  1166.         closewin(&cwinp);
  1167.         manrecur = False;
  1168.     }
  1169. }
  1170.  
  1171. /**********************  UNIT INITIALIZATION/EXIT CODE  *********************/
  1172.  
  1173. void man_exit(void)
  1174. {
  1175.     if ((manstate == _opened) || (manstate == _located)) {
  1176.         if (manstate == _opened) {
  1177.             outdev[0] = '\0';
  1178.             pageno = 1;
  1179.             manrecur = False;
  1180.             db_free(mpages);
  1181.             db_free(mchaps);
  1182.         }
  1183.         _close(manfile);
  1184.         manstate = _closed;
  1185.     }
  1186. }
  1187.  
  1188. void db_man_init(void)
  1189. {
  1190.     if (!initialized) {
  1191.         initialized = True;
  1192.         db_curs_init();
  1193.         db_funcs_init();
  1194.         db_gvar_init();
  1195.         db_heap_init();
  1196.         db_key_init();
  1197.         db_win_init();
  1198.         db_mnu_init();
  1199.         db_util_init();
  1200.         outdev[0] = '\0';
  1201.         pageno = 1;
  1202.         manrecur = False;
  1203.         morehelp = dispmanual;
  1204.         atexit(man_exit);
  1205.     }
  1206. }
  1207.  
  1208. /*****************************  END OF DB_MAN.C  ****************************/
  1209.